﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data.Entity;
using System.Globalization;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Business;
using Microsoft.AspNet.SignalR;

public partial class _Default : System.Web.UI.Page
{
    protected Utilities utilities = new Utilities();
    Utilities.Times allowedTimes = new Utilities.Times();
    ScheduleUtilities scheduleUtilities = new ScheduleUtilities();
    CalendarUtilities calendarUtilities = new CalendarUtilities();
    string defaultRoom;
    protected DateTime currentDate;
    protected int roomId;

    protected AlertMessage.MessageData alertMessageData = new AlertMessage.MessageData();

    protected void Page_Load(object sender, EventArgs e)
    {
        // Sätter lägsta och högsta tid för bokning. Hämtas från web.config > appSettings. Hittar också om vi har en defaultRoom-parameter
        allowedTimes.minTime = Convert.ToInt32(ConfigurationManager.AppSettings["timeStart"]);
        allowedTimes.maxTime = Convert.ToInt32(ConfigurationManager.AppSettings["timeEnd"]);
        defaultRoom = utilities.DefaultRoomRedirectExists(Request.QueryString["def"]);

        // Message-check
        alertMessageData = AlertMessage.OutputAlertMessage(Request.QueryString["m"]);
        
        // Bestämmer vilken dag som skall visas
        currentDate = DateHandler.CheckStringForDate(Request.QueryString["d"]);

        // Hanterar rumnavigationen
        roomId = Utilities.CheckStringForRoom(Request.QueryString["r"]);
        roomNav.InnerHtml += utilities.GetRoomHtml(roomId, currentDate, defaultRoom);

        // Skriver ut värden i kontroller
        PrepareDataControls();

        // När användaren lägger till en bokning
        if (Request.Form["hiddenBooking"] == "1")
        {
            CompleteBooking();
        }

        // Fixar länkarna och text för aktuell månad
        var pMonth = currentDate.AddMonths(-1);
        var nMonth = currentDate.AddMonths(1);

        var lastRef = roomId + defaultRoom;
        prevMonth.HRef = string.Format("?d={0:yyyy-MM-dd}&r={1}", pMonth, lastRef);
        nextMonth.HRef = string.Format("?d={0:yyyy-MM-dd}&r={1}", nMonth, lastRef);
        todayLink.HRef = string.Format("?d={0:yyyy-MM-dd}&r={1}", currentDate, lastRef);

        CheckHomeDestination();
    }

    // Skickar tillbaka besökaren efter 5 minuter
    protected void CheckHomeDestination()
    {   
        if (!string.IsNullOrEmpty(defaultRoom))
        {
            Response.AddHeader("REFRESH", "300;URL=?d=" + DateTime.Today.ToString("yyyy-MM-dd") + "&r=" + defaultRoom + "&def=" + defaultRoom);
        }
    }

    // Skriver ut en rad för varje timme i allowedTimes
    // Tiderna läggs även till med hel- och halvtimme i bokningsrutan som tidsalternativ för bokning
    protected void PrepareDataControls()
    {
        scheduleUtilities.FillTimeListDropDown(ddFrom, allowedTimes);
        scheduleUtilities.FillTimeListDropDown(ddTo, allowedTimes);

        scheduleUtilities.FillNameListDropDown(ddName);

        scheduleRepeater.DataSource = scheduleUtilities.FillSchedule(allowedTimes);
        scheduleRepeater.DataBind();
    }

    protected void CompleteBooking()
    {
        double from = utilities.CalculateTime(Request.Form["tBoxFrom"]);
        double to = utilities.CalculateTime(Request.Form["tBoxTo"]);
        int userId = Convert.ToInt32(Request.Form["ddName"]);
        string message = Request.Form["inputMessage"];

        // Sätter upp vilka timmar som bokningen avser
        DateTime timeFrom = currentDate.AddHours(from);
        DateTime timeTo = currentDate.AddHours(to);

        // Skapar en bokning och lägger in detaljerna i newBookingDetails
        ScheduleUtilities.BookingDetails newBookingDetails = scheduleUtilities.AddBooking(currentDate, timeFrom, timeTo, roomId, userId, message);

        // Få rätt sida i redirect
        string addBookingRedirect = scheduleUtilities.GetReturnPage(newBookingDetails, currentDate, roomId);

        // Skicka ut mail om bokningen
        MailHandler.SendBookingMail(newBookingDetails);

        BookingHub.SendToAll(currentDate.ToString("yyyy-MM-dd"), roomId);

        // Utan redirect refreshas bara sidan på POST, och då ligger informationen om att en POST gjorts kvar
        Response.Redirect(addBookingRedirect + defaultRoom);
    }

    protected void daySchedulePanel_Load(object sender, EventArgs e)
    {
        bookings.InnerHtml = scheduleUtilities.GetBookingBoxHtml(currentDate, roomId, allowedTimes, defaultRoom);
    }

    protected void calendarUpdatePanel_Load(object sender, EventArgs e)
    {
        calWeeks.InnerHtml = "";
        // En Lista skapas som innehåller alla dagar i månaden vi står på för tillfället
        List<DateTime> allDaysInCurrentMonth = new List<DateTime>();

        int daysInMonth = DateHandler.GetDaysInContainingMonth(currentDate);

        for (int i = 1; i <= daysInMonth; i++)
        {
            allDaysInCurrentMonth.Add(new DateTime(currentDate.Year, currentDate.Month, i));
        }

        // Ännu en lista av typen DateTime som innehåller en av varje datum och grupperar på vecka
        List<DateTime> sortDaysByWeek = allDaysInCurrentMonth.GroupBy(w => DateHandler.GetWeekForDate(w)).Select(g => g.First()).ToList();

        // För varje datetime i sortDaysByWeek
        foreach (DateTime currentDayInWeek in sortDaysByWeek)
        {
            try
            {
                // Skriver ut veckonumret
                calWeeks.InnerHtml += calendarUtilities.GetWeekHtml(DateHandler.GetWeekForDate(currentDayInWeek));

                // Skriver ut alla dagar i den veckan
                foreach (DateTime loopedDate in allDaysInCurrentMonth.Where(w => DateHandler.GetWeekForDate(w) == DateHandler.GetWeekForDate(currentDayInWeek)))
                {
                    calWeeks.InnerHtml += calendarUtilities.GetDayHtml(currentDate, loopedDate, roomId, allowedTimes, defaultRoom);
                }
            }
            catch (Exception ex)
            {
                Response.Write(ex);
            }
            calWeeks.InnerHtml += calendarUtilities.GetEndHtml();
        }
        calWeeks.InnerHtml += calendarUtilities.GetEndHtml();
    }
}